package com.rescue.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rescue.constant.MessageConstant;
import com.rescue.constant.SysSettingConstant;
import com.rescue.context.BaseContext;
import com.rescue.exception.BaseException;
import com.rescue.forum.dto.CommentPageQueryDTO;
import com.rescue.forum.dto.SaveCommentDTO;
import com.rescue.forum.dto.UserCommentQueryDTO;
import com.rescue.forum.entity.*;
import com.rescue.forum.syssetting.AuditSet;
import com.rescue.forum.syssetting.CommentSet;
import com.rescue.forum.vo.CommentQueryVO;
import com.rescue.mapper.*;
import com.rescue.result.PageResult;
import com.rescue.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private LikeRecordMapper likeRecordMapper;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private SysSettingMapper sysSettingMapper;
    @Autowired
    private UserMessageMapper userMessageMapper;
    @Autowired
    private UserIntegralRecordMapper userIntegralRecordMapper;

    /**
     * 评论分页查询
     *
     * @param commentPageQueryDTO
     * @return
     */
    @Transactional
    public PageResult page(CommentPageQueryDTO commentPageQueryDTO) {
        PageHelper.startPage(commentPageQueryDTO.getPage(), commentPageQueryDTO.getPageSize());
        Page<CommentQueryVO> list = commentMapper.getByPCommentIdT(0, commentPageQueryDTO.getArticleId());
        list.forEach(commentQueryVO -> {
            //1加载点赞情况
            //根据评论Id与用户Id获取用户点赞情况
            List<LikeRecord> like = likeRecordMapper.getByCommentIdAndUserId(commentQueryVO.getCommentId(), BaseContext.getCurrentId());
            commentQueryVO.setLikeType(0);
            if (like.size() != 0) {
                commentQueryVO.setLikeType(1);
            }
            //2获取子评论
            List<CommentQueryVO> sonList = commentMapper.getByPCommentIdT(commentQueryVO.getCommentId(), commentPageQueryDTO.getArticleId());
            //给子评论添加用户点赞情况
            sonList.forEach(commentQueryVO1 -> {
                //根据评论Id与用户Id获取用户点赞情况
                List<LikeRecord> like1 = likeRecordMapper.getByCommentIdAndUserId(commentQueryVO1.getCommentId(), BaseContext.getCurrentId());
                commentQueryVO1.setLikeType(0);
                if (like1.size() != 0) {
                    commentQueryVO1.setLikeType(1);
                }
            });
            commentQueryVO.setChildren(sonList);
        });
        return new PageResult(list.getTotal(), list.getResult());
    }


    /**
     * 根据Id删除评论
     *
     * @param commentId
     */
    @Transactional
    public void deleteById(Integer commentId) {
        int deleteCount = 0;
        String articleId = commentMapper.getById(commentId).getArticleId();
        //如果该评论为一级评论删除子评论
        List<ForumComment> list = commentMapper.getByPCommentId(commentId);
        if (list != null && list.size() > 0) {
            List<Integer> idList = list.stream()
                    .map(ForumComment::getCommentId)
                    .collect(Collectors.toList());
            //批量删除子评论
            commentMapper.deleteBatch(idList);
            deleteCount += list.size();
        }
        //删除该评论
        commentMapper.deleteById(commentId);
        deleteCount++;
        //修改对应文章的评论数
        articleMapper.updateCommentCount(articleId, -deleteCount);
    }

    /**
     * 审核评论
     *
     * @param commentId
     */
    public void audit(Integer commentId) {
        commentMapper.auditComment(commentId);
    }

    /**
     * 用户查询评论
     *
     * @param userCommentQueryDTO
     * @return
     */
    public PageResult userGetCommentList(UserCommentQueryDTO userCommentQueryDTO) {
        PageHelper.startPage(userCommentQueryDTO.getPage(), userCommentQueryDTO.getPageSize());
        Page<CommentQueryVO> list = commentMapper.getByPComment(0, userCommentQueryDTO);
        Integer userId = BaseContext.getCurrentId();
        list.forEach(commentQueryVO -> {
            //1加载点赞情况
            //根据评论Id与用户Id获取用户点赞情况
            List<LikeRecord> like = likeRecordMapper.getByCommentIdAndUserId(commentQueryVO.getCommentId(), userId);
            commentQueryVO.setLikeType(0);
            if (like.size() != 0) {
                commentQueryVO.setLikeType(1);
            }
            //添加头像
            commentQueryVO.setAvatar(userInfoMapper.getByUserId(commentQueryVO.getUserId()).getAvatar());
            //2获取子评论
            List<CommentQueryVO> sonList = commentMapper.getByPComment(commentQueryVO.getCommentId(), userCommentQueryDTO);
            //给子评论添加用户点赞情况
            sonList.forEach(commentQueryVO1 -> {
                //根据评论Id与用户Id获取用户点赞情况
                List<LikeRecord> like1 = likeRecordMapper.getByCommentIdAndUserId(commentQueryVO1.getCommentId(), userId);
                commentQueryVO1.setLikeType(0);
                if (like1.size() != 0) {
                    commentQueryVO1.setLikeType(1);
                }
                //添加头像
                commentQueryVO1.setAvatar(userInfoMapper.getByUserId(commentQueryVO1.getUserId()).getAvatar());
            });
            commentQueryVO.setChildren(sonList);
        });
        return new PageResult(list.getTotal(), list.getResult());
    }

    /**
     * @param saveCommentDTO
     */
    @Transactional
    public void save(SaveCommentDTO saveCommentDTO) {
        UserInfo curUser = userInfoMapper.getByUserId(BaseContext.getCurrentId());
        UserInfo replyUser = null;
        ForumArticle curArticle = articleMapper.getById(saveCommentDTO.getArticleId());
        if (saveCommentDTO.getPCommentId() != 0) {
            replyUser = userInfoMapper.getByUserId(saveCommentDTO.getReplyUserId());
        }
        String commentSet = sysSettingMapper.getByCode(SysSettingConstant.COMMENT_SETTING);
        CommentSet cSet = JSON.parseObject(commentSet, CommentSet.class);
        Integer needIntegral = cSet.getCommentIntegral();
        //如果积分不足，失败
        if (curUser.getCurrentIntegral() < needIntegral) {
            throw new BaseException(MessageConstant.INSUFFICIENT_INTEGRATION);
        }
        //判断是否需要审核
        String auditS = sysSettingMapper.getByCode(SysSettingConstant.AUDIT_SETTING);
        AuditSet auditSet = JSON.parseObject(auditS, AuditSet.class);
        //新增评论表
        commentMapper.save(ForumComment.builder()
                .pCommentId(saveCommentDTO.getPCommentId())
                .articleId(saveCommentDTO.getArticleId())
                .content(saveCommentDTO.getContent())
                .imgPath(saveCommentDTO.getImagePath())
                .userId(curUser.getUserId())
                .nickName(curUser.getNickName())
                .userIpAddress(curUser.getLastLoginIpAddress())
                .replyUserId(saveCommentDTO.getReplyUserId())
                .replyNickName(replyUser == null ? null : replyUser.getNickName())
                .postTime(LocalDateTime.now())
                .status(auditSet.getCommentAudit() ? 0 : 1).build());
        //修改文章评论数
        articleMapper.update(ForumArticle.builder()
                .articleId(saveCommentDTO.getArticleId())
                .commentCount(1).build());
        //修改个人积分
        userInfoMapper.update(UserInfo.builder()
                .currentIntegral(-needIntegral).userId(curUser.getUserId()).build());
        //增加积分记录表
        userIntegralRecordMapper.insert(UserIntegralRecord.builder()
                .userId(curUser.getUserId())
                .operType(UserIntegralRecord.COMMENT)
                .integral(cSet.getCommentIntegral())
                .operTypeName(UserIntegralRecord.TYPE_COMMENT)
                .createTime(LocalDateTime.now()).build());
        //新增消息表
        if (saveCommentDTO.getPCommentId() != 0) {
            //发送给评论回复人
            assert replyUser != null;
            userMessageMapper.save(UserMessage.builder()
                    .receivedUserId(replyUser.getUserId())
                    .articleId(saveCommentDTO.getArticleId())
                    .articleTitle(curArticle.getTitle())
                    .messageType(UserMessage.TYPE_COMMENT_MESSAGE)
                    .sendUserId(curUser.getUserId())
                    .sendNickName(curUser.getNickName())
                    .messageContent("回复了您")
                    .createTime(LocalDateTime.now())
                    .commentId(saveCommentDTO.getReplyCommentId())
                    .build());
        } else {
            //发送给文章作者
            userMessageMapper.save(UserMessage.builder()
                    .receivedUserId(curArticle.getUserId())
                    .articleId(saveCommentDTO.getArticleId())
                    .articleTitle(curArticle.getTitle())
                    .messageType(UserMessage.TYPE_COMMENT_MESSAGE)
                    .sendUserId(curUser.getUserId())
                    .sendNickName(curUser.getNickName())
                    .messageContent("回复了您")
                    .createTime(LocalDateTime.now())
                    .build());
        }
    }

    /**
     * 评论置顶取消置顶
     *
     * @param commentId
     * @param topType
     */
    public void top(Integer commentId, Integer topType) {

        commentMapper.update(ForumComment.builder().commentId(commentId)
                .topType(topType).build());
    }

    /**
     * 评论点赞/取消
     *
     * @param commentId
     * @param status
     */
    @Transactional
    public void doLike(Integer commentId, Integer status) {

        Integer userId = BaseContext.getCurrentId();
        //当前评论
        ForumComment comment = commentMapper.getById(commentId);

        //当前文章
        ForumArticle curArticle = articleMapper.getById(comment.getArticleId());

        //当前用户
        UserInfo curUser = userInfoMapper.getByUserId(userId);
        //添加或删除用户点赞记录表 like_record
        List<LikeRecord> list = likeRecordMapper.getByCommentIdAndUserId(commentId, userId);
        if (status == 1 && list.size() == 0) {
            //点赞
            likeRecordMapper.save(LikeRecord.builder()
                    .opType(LikeRecord.COMMENT)
                    .commentId(commentId)
                    .userId(userId)
                    .createTime(LocalDateTime.now())
                    .authorUserId(comment.getUserId())
                    .build());
            //修改评论点赞数
            commentMapper.update(ForumComment.builder().commentId(commentId)
                    .goodCount(1).build());
            //添加消息表user_message

            userMessageMapper.save(UserMessage.builder()
                    .receivedUserId(comment.getUserId())
                    .articleId(comment.getArticleId())
                    .articleTitle(curArticle.getTitle())
                    .commentId(commentId)
                    .sendUserId(userId)
                    .sendNickName(curUser.getNickName())
                    .messageType(UserMessage.TYPE_COMMENT_LIKE)
                    .messageContent(curUser.getNickName() + "赞了你的评论(" + comment.getContent() + ")").build());

        } else if (status == 0 && list.size() > 0) {
            //取消点赞
            likeRecordMapper.delete(list);
            //修改评论点赞数
            commentMapper.update(ForumComment.builder().commentId(commentId)
                    .goodCount(-1).build());
        }

    }

    /**
     * 获取当前用户评论
     *
     * @return
     */
    public List<ForumComment> getCommentByUserId() {
        return commentMapper.getByUserId(BaseContext.getCurrentId());
    }

    /**
     * 删除评论
     *
     * @param commentId
     */
    public void userDeleteById(Integer commentId) {
        ForumComment comment = commentMapper.getById(commentId);
        if (comment == null) {
            throw new BaseException(MessageConstant.INFORMATION_NOT_EXIST);
        }
        if (!Objects.equals(comment.getUserId(), BaseContext.getCurrentId())) {
            throw new BaseException(MessageConstant.DELETION_FAILURE);
        }
        deleteById(commentId);
    }

    /**
     * 插叙某天发布的评论数
     *
     * @param localDateTime
     * @return
     */
    public Integer getCommentCount(LocalDateTime localDateTime) {
        return commentMapper.getCommentCount(localDateTime.toLocalDate(), BaseContext.getCurrentId());
    }
}
